<!-- 工具公用按钮 -->
<template>
  <!-- 锚点 -->
  <AffixPanel :top="`${buttonTop}px`"
              right="1px"
              :dom="renderValues.affixTargetDom">
    <template #content>
      <Button icon="pi pi-cog"
              class="sidebar-button"
              ref="sidebarButton"
              :style="sidebarRunStyle"
              @click.stop="viewSidebarClickHandler"/>
    </template>
  </AffixPanel>
  <!-- 显示隐藏组件 -->
  <Sidebar v-model:visible="visibleSidebar"
           id="sidebar"
           ref="sidebar"
           :position="renderValues.position"
           :baseZIndex="10000"
           :modal="renderValues.modal"
           :showCloseIcon="renderValues.showCloseIcon"
           :class="renderValues.customerSiderbarClass">
    <slot name="sidebarContent"></slot>
  </Sidebar>
</template>

<script lang="ts" setup>
/** JS */
import {ref, Ref, watch, nextTick, withDefaults, defineProps, reactive, onMounted, defineEmits} from 'vue';
/** 组件 */
import AffixPanel from '@/components/panel/AffixPanel.vue';
import Sidebar from 'primevue/sidebar';

type SidebarPositionType = 'left' | 'right' | 'top' | 'bottom' | 'full' | undefined;


interface ToolButtonProps {
  /** 定位的目标元素 */
  affixTargetDom: HTMLElement | Element | undefined | null
  /** sidebar 数据 */
  position: SidebarPositionType
  modal: boolean
  showCloseIcon: boolean,
  /** 自定义 sidebar class */
  customerSiderbarClass?: string,
  top: number;
}

const props = withDefaults(defineProps<ToolButtonProps>(), {
      position: 'right',
      modal: true,
      showCloseIcon: false,
      top: 0
    }),
    renderValues: ToolButtonProps = reactive({
      affixTargetDom: props.affixTargetDom,
      position: props.position,
      modal: props.modal,
      showCloseIcon: props.showCloseIcon,
      customerSiderbarClass: props.customerSiderbarClass
    }),
    emits = defineEmits(['open'])

watch(props, (n) => {
  Object.assign(renderValues, n)
}, {deep: true});

/** 动态适应性 px 高度 */
let buttonTop = ref(0);
/** 元素钩子 */
let sidebar = ref(null), sidebarButton = ref(null);
/** Sidebar 显隐以及按钮动画 */
let visibleSidebar = ref(false), saveWidth = ref(0), sidebarRunStyle = ref('');
const viewSidebarClickHandler = (mode: number) => {
      visibleSidebar.value = !visibleSidebar.value;
      emits('open', visibleSidebar.value);
    },
    sidebarButtonAnimateHandler = (judge: boolean) => {
      const openClass = 'sidebar-cog-720', closeClass = 'sidebar-cog-0';
      let buttonEl = (sidebarButton.value as any).$el;
      let classList = buttonEl.children[0].classList;
      if (judge) {
        if (classList.contains(closeClass)) {
          buttonEl.children[0].classList.remove(closeClass);
        }
        buttonEl.children[0].classList.add(openClass);
      } else {
        if (classList.contains(openClass)) {
          buttonEl.children[0].classList.remove(openClass);
        }
        buttonEl.children[0].classList.add(closeClass);
      }
    }
watch(() => visibleSidebar.value, (n, o) => {
  // 需要加 nextTick 因为 sidebar 是 if 动态渲染，需要在 sidebar 渲染完毕后执行
  nextTick(() => {
    if (n) {
      let doc = document.getElementById('sidebar');
      if (doc) {
        let width = doc.clientWidth;
        if (sidebar.value) {
          sidebarRunStyle.value = `transform: translateX(-${width}px)`
          saveWidth.value = width;
        }
      }
    } else {
      sidebarRunStyle.value = `transform: translateX(1px);`
    }
    sidebarButtonAnimateHandler(n);
  });
})

onMounted(() => {
  nextTick(() => {
    // 计算高度，客户端页面高度的 1/2
    if (renderValues.affixTargetDom) {
      let clientHeight = Math.floor(document.documentElement.clientHeight / 2);
      // let htmlEle = renderValues.affixTargetDom as HTMLElement;
      if (props.top != 0) {
        buttonTop.value = clientHeight + props.top;
      } else {
        buttonTop.value = clientHeight;
      }
    }
  })

})
</script>

<style lang="less" scoped>

</style>